<?php

namespace lc\wechat\wxpay;

use lc\wechat\wxpay\base\WxPayHelper;
use lc\wechat\wxpay\base\WxPayException;
use lc\wechat\wxpay\base\WxPayConfig;
use think\facade\Config;

/**
 * 微信支付类
 * 接口访问类，包含所有微信支付API列表的封装，类中方法为static方法，
 * 每个接口有默认超时时间（除提交被扫支付为10s，上报超时时间为1s外，其他均为6s）
 * @package lc\wxpay
 */
class WxPayApi
{
    /**
     * @desc    企业付款到零钱(用于企业向微信用户个人付款)
     * @param   array 	$params 	接口请求参数
     * @return  array
     * @throws  base\WxPayException
     */
    public static function payToBalance(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';

		new WxPayConfig();
		$base = [
			'mch_appid' 		=> Config::get('lc.wxpay.appid', WxPayConfig::$appId),
			'mchid' 			=> WxPayConfig::$mchId,
			'spbill_create_ip' 	=> $_SERVER['REMOTE_ADDR'],
			'nonce_str' 		=> uniqid(),
		];
		$params = array_merge($base, $params);

        return WxPayHelper::sendRedPackRequest(1, $url, array_merge($base, $params));
    }

    /**
     * @desc    查询企业付款到零钱(用于企业向微信用户个人付款)
     * @param   array 	$params 	接口请求参数
     * @return  array
     * @throws  base\WxPayException
     */
    public static function queryBalance(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo';

		new WxPayConfig();
		$base = [
			'appid' 		    => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
			'mch_id' 			=> WxPayConfig::$mchId,
			'nonce_str' 		=> uniqid(),
		];
		$params = array_merge($base, $params);

        return WxPayHelper::queryRequest(1, $url, array_merge($base, $params));
    }

    /**
     * @desc    查询现金红包红包记录
     * @param   array 	$params 	接口请求参数
     * @return  array
     * @throws  base\WxPayException
     */
    public static function queryRedPack(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo';

        new WxPayConfig();
        $base = [
            'appid' 		    => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id' 			=> WxPayConfig::$mchId,
            'nonce_str' 		=> uniqid(),
            'bill_type'         => 'MCHT'
        ];
        $params = array_merge($base, $params);

        return WxPayHelper::queryRequest(1, $url, array_merge($base, $params));
    }

    /**
	 * @desc 	发放现金红包
	 * @param   array 	$params 	接口请求参数
     * @return  array
     * @throws  WxPayException
     */
    public static function sendRedPack(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';

        new WxPayConfig();
		$base = [
			'wxappid' 	=> Config::get('lc.wxpay.appid', WxPayConfig::$appId),
			'mch_id' 	=> WxPayConfig::$mchId,
			'client_ip' => $_SERVER['REMOTE_ADDR'],
			'nonce_str' => uniqid(),
		];
		$params = array_merge($base, $params);

        return WxPayHelper::sendRedPackRequest(2, $url, array_merge($base, $params));
    }

    /**
     * @desc    微信支付统一下单
     * @param   array 	$params 	接口请求参数
     * @return  array
     * @throws  WxPayException
     */
    public static function unifiedOrder(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';

        new WxPayConfig();
        $base = [
            'appid' 	        => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id' 	        => WxPayConfig::$mchId,
            'spbill_create_ip'  => $_SERVER['REMOTE_ADDR'],
            'nonce_str'         => uniqid(),
        ];

        return WxPayHelper::sendUnifyRequest($url, array_merge($base, $params), 'unifiedOrder');
    }

    /**
     * @desc    查询订单
     * @param   string $transactionId 微信订单号
     * @return  array
     * @throws  WxPayException
     */
    public static function queryByTransactionId(string $transactionId)
    {
        return self::queryOrder(['transaction_id' => $transactionId]);
    }

    /**
     * @desc    查询订单
     * @param   string $outTradeNo 商户订单号
     * @return  array
     * @throws  WxPayException
     */
    public static function queryByOutTradeNumber(string $outTradeNo)
    {
        return self::queryOrder(['out_trade_no' => $outTradeNo]);
    }

    /**
     * @desc    申请退款
     * @param   string  $transactionId  微信订单号
     * @param   array   $params         接口请求参数
     * @return  array
     * @throws  WxPayException
     */
    public static function refundByTransactionId(string $transactionId, array $params)
    {
        return self::refund(array_merge(['transaction_id' => $transactionId], $params));
    }

    /**
     * @desc    申请退款
     * @param   string  $outTradeNo 微信订单号
     * @param   array   $params     接口请求参数
     * @return  array
     * @throws  WxPayException
     */
    public static function refundByOutTradeNumber(string $outTradeNo, array $params)
    {
        return self::refund(array_merge(['out_trade_no' => $outTradeNo], $params));
    }

    /**
     * @desc    微信订单号退款查询
     * @param   string $transactionId 微信订单号
     * @return  array
     * @throws  WxPayException
     */
    public static function queryRefundByTransactionId(string $transactionId)
    {
        return self::refundQuery(['transaction_id' => $transactionId]);
    }

    /**
     * @desc    商户订单号退款查询
     * @param   string $outTradeNo 商户订单号
     * @return  array
     * @throws  WxPayException
     */
    public static function queryRefundByOutTradeNumber(string $outTradeNo)
    {
        return self::refundQuery(['out_trade_no' => $outTradeNo]);
    }

    /**
     * @desc    商户退款单号退款查询
     * @param   string $outRefundNo 商户退款单号
     * @return  array
     * @throws  WxPayException
     */
    public static function queryRefundByOutRefundNumber(string $outRefundNo)
    {
        return self::refundQuery(['out_refund_no' => $outRefundNo]);
    }

    /**
     * @desc    微信退款单号退款查询
     * @param   string $refundId
     * @return  array
     * @throws  WxPayException
     */
    public static function queryRefundByRefundId(string $refundId)
    {
        return self::refundQuery(['refund_id' => $refundId]);
    }

    /**
     * @desc    微信支付订单查询
     * @param   array 	$params 	接口请求参数
     * @return  array
     * @throws  WxPayException
     */
    private static function queryOrder(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/pay/orderquery';

        new WxPayConfig();
        $base = [
            'appid' 	        => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id' 	        => WxPayConfig::$mchId,
            'nonce_str'         => uniqid(),
        ];

        return WxPayHelper::sendUnifyRequest($url, array_merge($base, $params), 'queryOrder');
    }

    /**
     * @desc    微信支付关闭订单
     * @param   string $outTradeNo 订单号
     * @return  array
     * @throws  WxPayException
     */
    public static function closeOrder(string $outTradeNo)
    {
        $url = 'https://api.mch.weixin.qq.com/pay/closeorder';

        new WxPayConfig();
        $params = [
            'appid' 	        => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id' 	        => WxPayConfig::$mchId,
            'nonce_str'         => uniqid(),
            'out_trade_no'      => $outTradeNo
        ];

        return WxPayHelper::sendUnifyRequest($url, $params, 'closeOrder');
    }

    /**
     * @desc    微信支付申请退款
     * @param   array 	$params 接口请求参数
     * @return  array
     * @throws  WxPayException
     */
    private static function refund(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund';

        new WxPayConfig();
        $base = [
            'appid' 	        => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id' 	        => WxPayConfig::$mchId,
            'nonce_str'         => uniqid(),
        ];
        $params = array_merge($base, $params);

        return WxPayHelper::sendUnifyRequest($url, $params, 'refund');
    }

    /**
     * @desc    微信支付退款查询
     * @param   array 	$params 接口请求参数
     * @return  array
     * @throws  WxPayException
     */
    private static function refundQuery(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/pay/refundquery';

        new WxPayConfig();
        $base = [
            'appid' 	        => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id' 	        => WxPayConfig::$mchId,
            'nonce_str'         => uniqid(),
        ];
        $params = array_merge($base, $params);

        return WxPayHelper::sendUnifyRequest($url, $params, 'refundQuery');
    }

    /**
     * 微信发送商家优惠券
     *
     * @param array $params
     * @return array
     */
    public static function unifiedOrderForCoupon(array $params)
    {
        $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/send_coupon';
        new WxPayConfig();
        $base = [
            'appid'             => Config::get('lc.wxpay.appid', WxPayConfig::$appId),
            'mch_id'            => WxPayConfig::$mchId,
            'nonce_str'         => uniqid(),
        ];
        return WxPayHelper::sendUnifyRequest($url, array_merge($base, $params), 'send_coupon');
    }
}

